package com.yiguantong.police.ui.utils;

import android.content.pm.ApplicationInfo;
import android.os.Environment;
import android.util.Log;

import com.MainApplication;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 类名称：MyLog 作者： 王中伏 创建时间：2013-7-25 类描述：日志操作类 版权声明 : Copyright (C) 2012-2014
 * 南京欣网 修改时间：上午9:29:43
 */
public final class MyLog {
    /**
     * 开发期log
     * <p/>
     * {打包时需要关闭}
     */
    private static boolean MY_DEVELOPING_LOG = true;

    /**
     * 写入sd卡的日志级别
     * <p/>
     * {打包需调整为WARN级别，开发期暂时用DEBUG级别}
     */
    private static final int OUT_LEVEL = Log.ERROR;

    /**
     * 日志写入SD卡的开关
     */
    private static boolean MYLOG_WRITE_SD_SWITCH = true;

    /**
     * 日志文件夹
     */
    private static final String LOG_FILE_NAME = "sdmcc/log/";

    /**
     * 写入日志至SD卡文件路径
     */
    private static String MYLOG_SD_DIR = Environment.getExternalStorageDirectory().getPath();

    /**
     * SD卡中日志文件的最多保存天数
     */
    private static int SDCARD_LOG_FILE_SAVE_DAYS = 1;

    /**
     * SD卡中保存日志的文件
     */
    private static String MYLOG_SD_FILE = "log.txt";

    /**
     * 日志的输出格式
     */
    private static SimpleDateFormat mylogsdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 文件写入流
     */
    private static FileWriter fileWriter;

    /**
     * 缓冲写入
     */
    private static BufferedWriter bufferedWriter;

    /**
     * 日志文件
     */
    private static File logFile;

    /**
     * 方法名称：e 作者：王中伏 方法描述：错误日志 输入参数:@param tag 标志 输入参数:@param msg 信息 返回类型：void
     * 备注：
     */
    public static void e(String tag, String text) {
        log(tag, "[" + tag + "]" + text, Log.ERROR);
    }

    /**
     * 方法名称：e 作者：王中伏 方法描述：错误日志 输入参数:@param tag 标志 输入参数:@param msg 信息 返回类型：void
     * 备注：
     */
    public static void i(String tag, String text) {
        log(tag, "[" + tag + "]" + text, Log.INFO);
    }

    /**
     * 方法名称：w 作者：王中伏 方法描述：警告日志 输入参数:@param tag 标志 输入参数:@param msg 信息 返回类型：void
     * 备注：
     */
    public static void w(String tag, String text) {
        log(tag, "[" + tag + "]" + text, Log.WARN);
    }

    /**
     * 方法名称：d 作者：王中伏 方法描述：debug日志 输入参数:@param tag 输入参数:@param msg 返回类型：void 备注：
     */
    public static void d(String tag, String text) {
        log(tag, "[" + tag + "]" + text, Log.DEBUG);
    }

    /**
     * 方法名称：d 作者：王中伏 方法描述：debug日志 输入参数:@param tag 输入参数:@param msg 返回类型：void 备注：
     */
    public static void v(String tag, String text) {
        log(tag, "[" + tag + "]" + text, Log.VERBOSE);
    }

    /**
     * 记录错误异常堆栈信息
     * <p>
     * 方法名称：
     * <p>
     * 方法描述：
     *
     * @param tag
     * @param exp <p>
     *            备注：
     * @author wanglinqi
     */
    public static void e(String tag, String prompt, Throwable exp) {
        if (exp == null) {
            return;
        }
        e(tag, prompt + "\n");
        printTrace(tag, exp, false);
    }

    /**
     * 记录错误堆栈信息
     * <p>
     * 方法名称：printTrace
     * <p>
     * 方法描述：
     *
     * @param tag
     * @param e
     * @param isCase <p>
     *               备注：
     * @author wanglinqi
     */
    private static void printTrace(String tag, Throwable e, boolean isCase) {
        StringBuffer err = new StringBuffer();
        if (isCase) {
            err.append("Caused by: ");
        }
        err.append(e.toString());
        err.append("\n");

        StackTraceElement[] stack = e.getStackTrace();
        if (stack != null) {
            for (int i = 0; i < stack.length; i++) {
                err.append("\tat ");
                err.append(stack[i].toString());
                err.append("\n");
            }
            e(tag, err.toString());
        }

        Throwable cause = e.getCause();
        if (cause != null) {
            printTrace(tag, cause, true);
        }
    }

    /**
     * 方法名称：log 作者：王中伏 方法描述：日志输入类 输入参数:@param tag 日志标志 输入参数:@param msg 日志内容
     * 输入参数:@param level 日志等级 返回类型：void 备注：
     */
    private static void log(String tag, String msg, int level) {
        if (Debug.logable) {
            switch (level) {
                case Log.VERBOSE:
                    Log.v(tag, msg);
                    break;
                case Log.DEBUG:
                    Log.d(tag, msg);
                    break;
                case Log.INFO:
                    Log.i(tag, msg);
                    break;
                case Log.WARN:
                    Log.w(tag, msg);
                    break;
                case Log.ERROR:
                    Log.e(tag, msg);
                    break;
                default:
                    break;
            }
        }

        // 将日志写入SD卡,日志只记录警告和错误级别日志
        if (MYLOG_WRITE_SD_SWITCH && level >= OUT_LEVEL) {
            writeLogToSd(String.valueOf(level), tag, msg);
        }
    }

    /**
     * 方法名称：writeLogToSd 作者：王中伏 方法描述：将日志写入SD卡 输入参数:@param levelStr 等级字符串
     * 输入参数:@param tag 日志标志 输入参数:@param msg 日志信息 返回类型：void 备注：
     */
    private synchronized static void writeLogToSd(String levelStr, String tag, String msg) {
        Date nowDate = new Date();
        SimpleDateFormat filelog = new SimpleDateFormat("yyyy-MM-dd");
        String needWriteFile = filelog.format(nowDate);
        String needWriteMessageTitle = mylogsdf.format(nowDate) + " " + levelStr + " " + tag;
        String needWriteLog = msg;
        if (isUseSD()) {
            try {
                File file = new File(MYLOG_SD_DIR + File.separator + LOG_FILE_NAME);
                if (!file.exists()) {
                    file.mkdir();
                }
                logFile = new File(MYLOG_SD_DIR + File.separator + LOG_FILE_NAME + File.separator
                        + needWriteFile + MYLOG_SD_FILE);
                if (!logFile.exists()) {
                    logFile.createNewFile();
                }
                fileWriter = new FileWriter(logFile, true);
                bufferedWriter = new BufferedWriter(fileWriter);
                bufferedWriter.write(needWriteMessageTitle);
                bufferedWriter.newLine();
                bufferedWriter.write(needWriteLog);
                bufferedWriter.newLine();
                bufferedWriter.write("\n");
                bufferedWriter.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                closeWriter(fileWriter);
                closeWriter(bufferedWriter);
            }
        } else {
            MainApplication.getIns().tip("sd卡不能使用");
        }

    }

    /**
     * 方法名称：closeWriter 作者：王中伏 方法描述：关闭写入流 输入参数:@param writer 返回类型：void 备注：
     */
    private static void closeWriter(Writer writer) {
        try {
            if (null != writer) {
                writer.close();
                writer = null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 方法名称：sdIsUse 作者：王中伏 方法描述：SD卡是否可以使用 输入参数:@return 返回类型：boolean 备注：
     */
    private static boolean isUseSD() {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }

    /**
     * 方法名称：delLogFile 作者：王中伏 方法描述：删除日志 输入参数: 返回类型：void 备注：
     */
    @SuppressWarnings("deprecation")
    public static void delLogFile() {
        Date nowDate = new Date();
        Calendar nowCalendar = Calendar.getInstance();
        nowCalendar.setTime(nowDate);
        nowCalendar.set(Calendar.DATE, nowDate.getDate() - SDCARD_LOG_FILE_SAVE_DAYS);

        SimpleDateFormat filelog = new SimpleDateFormat("yyyy-MM-dd");
        String needDelLog = filelog.format(nowCalendar.getTime());
        File delLogFile = new File(MYLOG_SD_DIR + File.separator + LOG_FILE_NAME + File.separator
                + needDelLog + MYLOG_SD_FILE);
        if (delLogFile.exists()) {
            delLogFile.delete();
        }
    }

    public interface Debug {
        public final boolean logable = isDebugMode();
    }

    /**
     * 判断是否是debug模式
     *
     * @return
     */
    public static boolean isDebugMode() {
        try {
            MainApplication application = MainApplication.getIns();
            ApplicationInfo info = application.getApplicationInfo();
            return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    public static void d(String msg) {
        if (msg == null)
            return;
        if (Debug.logable) {
            if (msg.length() > 3000) {
                for (int i = 0; i < msg.length(); i += 3000) {
                    if (i + 3000 < msg.length())
                        Log.d("--sdcmcc--", msg.substring(i, i + 3000));
                    else
                        Log.d("--sdcmcc--", msg.substring(i, msg.length()));
                }
            } else {
                Log.d("--sdcmcc--", msg);
            }
        }
    }

    public static void i(String msg) {
        if (msg == null)
            return;
        if (Debug.logable) {
            if (msg.length() > 3000) {
                for (int i = 0; i < msg.length(); i += 3000) {
                    if (i + 3000 < msg.length())
                        Log.i("--sdcmcc--", msg.substring(i, i + 3000));
                    else
                        Log.i("--sdcmcc--", msg.substring(i, msg.length()));
                }
            } else {
                Log.i("--sdcmcc--", msg);
            }
        }
    }

    public static void e(String msg) {
        if (msg == null)
            return;
        if (Debug.logable) {
            if (msg.length() > 3000) {
                for (int i = 0; i < msg.length(); i += 3000) {
                    if (i + 3000 < msg.length())
                        Log.e("--sdcmcc--", msg.substring(i, i + 3000));
                    else
                        Log.e("--sdcmcc--", msg.substring(i, msg.length()));
                }
            } else {
                Log.e("--sdcmcc--", msg);
            }
        }
    }
}
